load("@rules_motoko//motoko:defs.bzl", "motoko_binary", "motoko_library")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
load("//bazel:defs.bzl", "rust_ic_test_suite")
load("//bazel:prost.bzl", "generated_files_check")
load("//bazel/candid:defs.bzl", "did_git_test")

package(default_visibility = ["//visibility:public"])

exports_files([
    "canister_ids.json",
    "ledger.did",
    "ledger_archive.did",
])

filegroup(
    name = "protos",
    srcs = glob(["proto/**"]),
)

rust_library(
    name = "icp_ledger",
    srcs = glob([
        "src/**",
    ]),
    crate_name = "icp_ledger",
    proc_macro_deps = [
        # Keep sorted.
        "@crate_index//:strum_macros",
    ],
    version = "0.9.0",
    deps = [
        # Keep sorted.
        "//packages/ic-ledger-hash-of:ic_ledger_hash_of",
        "//packages/icrc-ledger-types:icrc_ledger_types",
        "//rs/crypto/sha2",
        "//rs/ledger_suite/common/ledger_canister_core",
        "//rs/ledger_suite/common/ledger_core",
        "//rs/rust_canisters/dfn_protobuf",
        "//rs/rust_canisters/on_wire",
        "//rs/types/base_types",
        "@crate_index//:candid",
        "@crate_index//:comparable",
        "@crate_index//:crc32fast",
        "@crate_index//:hex",
        "@crate_index//:ic-cdk",
        "@crate_index//:ic-stable-structures",
        "@crate_index//:prost",
        "@crate_index//:serde",
        "@crate_index//:serde_bytes",
        "@crate_index//:serde_cbor",
        "@crate_index//:strum",
    ],
)

rust_test(
    name = "icp_ledger_test",
    crate = ":icp_ledger",
    deps = [
        # Keep sorted.
        "@crate_index//:proptest",
    ],
)

motoko_library(
    name = "ledger_mo_lib",
    srcs = ["wasm/Ledger.mo"],
)

motoko_binary(
    name = "ledger_proxy",
    entry = "wasm/Proxy.mo",
    wasm_out = "ledger_proxy.wasm",
    deps = [":ledger_mo_lib"],
)

rust_ic_test_suite(
    name = "ledger_canister_integration_test",
    timeout = "long",
    srcs = [
        "tests/tests.rs",
        "tests/upgrade_downgrade.rs",
    ],
    compile_data = ["ledger_archive.did"],
    data = [
        "ledger.did",
        ":ledger_proxy.wasm",
        "//rs/ledger_suite/icp/archive:ledger-archive-node-canister-wasm",
        "//rs/ledger_suite/icp/index:ic-icp-index-canister",
        "//rs/ledger_suite/icp/ledger:ledger-canister-wasm",
        "//rs/pocket_ic_server:pocket-ic-server",
        "@mainnet_canisters//:archive.wasm.gz",
        "@mainnet_canisters//:index.wasm.gz",
        "@mainnet_canisters//:ledger.wasm.gz",
    ],
    env = {
        "CARGO_MANIFEST_DIR": "rs/ledger_suite/icp",
        "IC_ICP_INDEX_CANISTER_WASM_PATH": "$(rootpath //rs/ledger_suite/icp/index:ic-icp-index-canister)",
        "LEDGER_ARCHIVE_NODE_CANISTER_WASM_PATH": "$(rootpath //rs/ledger_suite/icp/archive:ledger-archive-node-canister-wasm)",
        "LEDGER_CANISTER_WASM_PATH": "$(rootpath //rs/ledger_suite/icp/ledger:ledger-canister-wasm)",
        "LEDGER_PROXY_WASM_PATH": "$(rootpath :ledger_proxy.wasm)",
        "MAINNET_ICP_INDEX_CANISTER_WASM_PATH": "$(rootpath @mainnet_canisters//:index.wasm.gz)",
        "MAINNET_ICP_LEDGER_ARCHIVE_NODE_CANISTER_WASM_PATH": "$(rootpath @mainnet_canisters//:archive.wasm.gz)",
        "MAINNET_ICP_LEDGER_CANISTER_WASM_PATH": "$(rootpath @mainnet_canisters//:ledger.wasm.gz)",
        "POCKET_IC_BIN": "$(rootpath //rs/pocket_ic_server:pocket-ic-server)",
    },
    deps = [
        # Keep sorted.
        ":icp_ledger",
        "//packages/ic-http-types",
        "//packages/ic-ledger-hash-of:ic_ledger_hash_of",
        "//packages/icrc-ledger-types:icrc_ledger_types",
        "//packages/pocket-ic",
        "//rs/canister_client/sender",
        "//rs/crypto/sha2",
        "//rs/ledger_suite/common/ledger_canister_core",
        "//rs/ledger_suite/common/ledger_core",
        "//rs/ledger_suite/icp/index:ic-icp-index",
        "//rs/ledger_suite/icp/test_utils",
        "//rs/rust_canisters/canister_test",
        "//rs/rust_canisters/dfn_protobuf",
        "//rs/rust_canisters/on_wire",
        "//rs/types/base_types",
        "@crate_index//:candid",
        "@crate_index//:candid_parser",
        "@crate_index//:hex",
        "@crate_index//:ic-management-canister-types",
        "@crate_index//:maplit",
        "@crate_index//:rand",
        "@crate_index//:rand_chacha",
        "@crate_index//:serde",
        "@crate_index//:serde_bytes",
    ],
)

# To run this test,
#
#     bazel \
#         test \
#         --test_env=SSH_AUTH_SOCK \
#         //rs/ledger_suite/icp:ledger_canister_integration_golden_nns_state_test
#
# The only unusual thing in this command is `--test_env=SSH_AUTH_SOCK`. That causes the
# SSH_AUTH_SOCK environment variable to be "forwarded" from your shell to the sandbox where the test
# is run. This authorizes the test to download the test data.
#
# Additionally, the following flags are recommended (but not required):
#
# --test_output=streamed
# --test_arg=--nocapture
#
# These let you watch the progress of the test, rather than only being able to see the output only
# at the end.
#
# See the .bazelrc for more configuration information.
rust_ic_test_suite(
    name = "ledger_canister_integration_golden_nns_state_test",
    # This uses on the order of 10 GB of disk space.
    # Therefore, size = "large" is not large enough.
    size = "enormous",
    srcs = [
        "tests/golden_nns_state.rs",
    ],
    data = [
        "//rs/ledger_suite/icp/archive:ledger-archive-node-canister-wasm",
        "//rs/ledger_suite/icp/index:ic-icp-index-canister",
        "//rs/ledger_suite/icp/ledger:ledger-canister-wasm-allowance-getter",
        "@mainnet_canisters//:archive.wasm.gz",
        "@mainnet_canisters//:index.wasm.gz",
        "@mainnet_canisters//:ledger.wasm.gz",
    ],
    env = {
        "CARGO_MANIFEST_DIR": "rs/ledger_suite/icp",
        "IC_ICP_INDEX_CANISTER_WASM_PATH": "$(rootpath //rs/ledger_suite/icp/index:ic-icp-index-canister)",
        "LEDGER_ARCHIVE_NODE_CANISTER_WASM_PATH": "$(rootpath //rs/ledger_suite/icp/archive:ledger-archive-node-canister-wasm)",
        "LEDGER_CANISTER_WASM_PATH": "$(rootpath //rs/ledger_suite/icp/ledger:ledger-canister-wasm-allowance-getter)",
        "MAINNET_ICP_INDEX_CANISTER_WASM_PATH": "$(rootpath @mainnet_canisters//:index.wasm.gz)",
        "MAINNET_ICP_LEDGER_ARCHIVE_NODE_CANISTER_WASM_PATH": "$(rootpath @mainnet_canisters//:archive.wasm.gz)",
        "MAINNET_ICP_LEDGER_CANISTER_WASM_PATH": "$(rootpath @mainnet_canisters//:ledger.wasm.gz)",
    },
    tags = [
        "fi_tests_nightly",  # Run this test in the fi-tests-nightly GitHub Action job.
        "no-sandbox",  # such that the test can access the file $SSH_AUTH_SOCK.
        "requires-network",  # Because mainnet state is downloaded (and used).
    ],
    deps = [
        # Keep sorted.
        ":icp_ledger",
        "//packages/icrc-ledger-types:icrc_ledger_types",
        "//rs/ledger_suite/common/ledger_core",
        "//rs/ledger_suite/icp/archive:ic-icp-archive",
        "//rs/ledger_suite/icp/index:ic-icp-index",
        "//rs/ledger_suite/icp/test_utils",
        "//rs/ledger_suite/test_utils/in_memory_ledger:ic-ledger-suite-in-memory-ledger",
        "//rs/ledger_suite/test_utils/state_machine_helpers:ic-ledger-suite-state-machine-helpers",
        "//rs/nns/test_utils/golden_nns_state",
        "//rs/rust_canisters/canister_test",
        "//rs/state_machine_tests",
        "//rs/types/base_types",
        "@crate_index//:candid",
        "@crate_index//:candid_parser",
    ],
)

rust_test(
    name = "protobuf_encoding_test",
    srcs = ["tests/protobuf_encoding.rs"],
    deps = [
        # Keep sorted.
        ":icp_ledger",
        "//packages/ic-ledger-hash-of:ic_ledger_hash_of",
        "//rs/ledger_suite/common/ledger_core",
        "//rs/rust_canisters/dfn_protobuf",
        "@crate_index//:proptest",
        "@crate_index//:serde_bytes",
    ],
)

did_git_test(
    name = "ledger_did_git_test",
    did = ":ledger.did",
)

generated_files_check(
    name = "check_generated_files",
    srcs = ["tests/check_generated_files.rs"],
    data = [
        ":protos",
        "//rs/types/base_types:protos",
    ] + glob(["src/gen/**"]),
    manifest_dir = "rs/ledger_suite/icp",
    deps = [
        # Keep sorted.
        "//rs/ledger_suite/icp/protobuf_generator:lib",
        "//rs/test_utilities/compare_dirs",
        "@crate_index//:tempfile",
    ],
)
